package io流;

import org.junit.Test;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class IOAPI {
    /**
     * 标准IO流---目的:数据传输  输出文本,图片
     * java定义一套标准流-->数据传输-->创建流:直接创建某个流对象
     * 标准流规则1:方向划分---输入流和输出流
     *                     输入流:读入 ---->文件--->相对于程序--->文件往程序走
     *                     InputStream(抽象类:定义所有读的方法)[学习:子实现类]
     *                     输出流:写入 ---->文件---->相对于程序---->程序写出
     *                     OutputStream(抽象类:定义所有写的方法)[学习:子实现类]
     *          2:功能划分
     *          低级流[节点流]:是建立在程序与数据源之间的"管道"
     *          功能:负责搬运的数据流,输入流和输出流都有自己的低级流
     *          特点:一个字节一个字节读或写的方法
     *          FileInPutStream     低级流继承InPutStream---文件输出流
     *          FileOutPutStream    低级流继承OutputStream---文件输入流
     *       高级流[处理流]:不能直接创建对象,不能独立存在
     *       功能:专门处理低级流以及其他高级流的流
     *       特点:搬运数据是,实现具体功能:效率提高流
     *
     *---总结:输入流和输出流,具备功能:低级流于高级流
     * 实际使用:明确是同具体流:明确使用具体流,每个流都有自己的功能
     */

/**                                       文件输入流
 *              输入流             低级流
 * 标准流  方向              功能            文件输出流:FileOutputStream
 *              输出流             高级流
 *需求:写出一个fos.txt
 * FileOutputStream 构造器使用
 * new FileOutputStream("路径+文件全称")
 * new FileOutputStream("路径+文件全称",boolean  append)
 * 写出文件的同时实现追加效果,第二个参数:true   追加
 *                                 false   默认不追加
 *new  FileOutputStream(File   file,boolean   append)
 * 写出文件,采用File传入路径+全称
 */
@Test
    public   void    testFos() throws IOException {
    //低级流---文件输出流对象---从程序中写出"文件:数据"
    FileOutputStream  fos=new FileOutputStream("fos.txt",true);
    //需求:fos.txt   增加一行文本   每次运行实现追加文本效果
    String say="嘻嘻";//字符串由字符数组构成--数组的功能getBytes()转换位字节数组
    //输出流---写功能:write(byte[]b) 写出字节数组
    fos.write(say.getBytes());
    //必须关闭流---目的:接受内存开销
    fos.close();
}
/**
 * 文件输入流:读入操作
 * FileInputStream   文件输入流
 * redd() 返回一个读取一个字节---效率低
 * redd(字节数组byte[]b)
 * 返回一个指定字节数组:"空间大小"的读取---效率高
 * 需求:读入fos.txt文件内容
 */
@Test
    public  void  testFis() throws IOException {
    //创建文件输入流---读入fos.txt文件内容
    FileInputStream  fis=new FileInputStream("fos.txt");
    //读入效率高:创建字节数组-指定控件为:10kb
    byte[]b=new byte[1024*10];
    //读入操作:read(字节数组)  以10kb读入数据
    int  len=fis.read(b);
    //写出:文本---字符串---针对流操作,提供构造器
    //                   文件按照"指定字节数组空间"写入程序中
    //                   从0开始写入程序,写道-1结束
    //                   len:十进制转换为二进制,写入,不等于-1,一直写入
    //一次性将给定数据按照字节数组指定空间大小,写出字符串,写出成字符串
    String str=new String(b,0,len);
    System.out.println(str);
}
/**
 * 需求:利用标准流实现视频复制粘贴
 */
@Test
    public  void testCV() throws IOException {
    //1.从"复制问及那.mp4"复制  操作---读入
    FileInputStream fis=new  FileInputStream("复制视频,MP4");
    //2.创建新文件"新文件.MP4"粘贴  操作---写出
    FileOutputStream fos=new FileOutputStream("最新视频.MP4");
    //3.保存每次读取的数据[字节量---int]
    int  len=-1;

    //4.一直 从"复制文件.MP4"  进行读入操作  不等于-1 一直读
    long s=System.currentTimeMillis();
    while ((len=fis.read())!=-1){
        fos.write(len);
    }
    long e=System.currentTimeMillis();
    System.out.println((e-s)/1000+"毫秒");
    //5.关闭流   ---测:效率低  --正常播放
    fos.close();
    fis.close();
}
/**
 * 需求：利用标准流实现视频复制粘贴--效率低
 *                              效率高--空间执行为：自定 100kb
 * 【高级流】BufferedInputStream   缓冲输入流---提升效率---内嵌缓存区【长度按照文件大小合理分配】
 *          BufferedOutputStream   缓冲输出流---提升效率--内嵌缓存区【长度按照文件大小合理分配】
 *高级流使用方法：1.处理低级流，套在低级流上
 *             2.直接使用高级流的方法
 *             3.高级流不能直接创建【不能独立存在】
 */
@Test
    public  void  testcv1() throws IOException {
    //1.创建低级流：读入“复制视频.mp4”
    FileInputStream fis=new FileInputStream("复制视频.MP4");
    //1.创建高级流套在低级流上【自带缓冲区：字节数组】
    BufferedInputStream bis=new BufferedInputStream(fis);
    //2.创建初级流：写出“高效视频.MP4”
    FileOutputStream fos=new FileOutputStream("高效视频.mp4");
    //2.创建高级流：套在低级流上【自带缓冲区：字节数组】
    BufferedOutputStream bos=new BufferedOutputStream(fos);
    //3.保存数据
    int len=1;
    //4.高级流--低级流方法一致---read（）读取内嵌缓冲区【字节数组】
    //高级流--低级流方法一致--write（）写出内嵌缓冲区【字节数组】
    //一直冲”复制视频.mp4"读取数据，不等于-1，一直读
    long  s=System.currentTimeMillis();
    while ((len=bis.read())!=-1){
        bos.write(len);
    }
    long e=System.currentTimeMillis();
    System.out.println("缓冲流【自带缓冲区】"+(e-s)+"毫秒");
    //关闭流--->高级流与低级流：都管--->高级流间歇性关闭低级流--->关闭高级流
    bis.close();//高级流--缓冲输入流
    bos.close();//高级流--缓冲输出流
    /*fis.close()//低级流--文件输入流
    fos.close()//低级流--文件输出流*/

}
/**
 * 高级流---缓冲流【内嵌缓冲区】
 * BufferedOutputStream  缓冲输出流
 * 需求：通过缓冲输出流实现从程序写出文件：bos.txt,写出内容
 */
@Test
    public  void   testBos() throws IOException {
    //1.创建低级流--->bos.txt
    FileOutputStream fos=new FileOutputStream("bos.txt");
    //2.创建高级流--->缓冲区：字节数组--合理【传输效率】
    BufferedOutputStream  bos=new BufferedOutputStream(fos);
    //3.写出文件文本内容
    String str="玩了五年骨架";
    //4.写出到bos.txt文件中：字符串转成字节数组--写出
    bos.write(str.getBytes());
    //5.将缓冲区数据一次性写出  flush（）【立即写出】
    //bos.flush();
    bos.close();//关闭流--一定把缓冲区数据全部写出
}













}
